package org.feng.demofx.pages;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import org.feng.demofx.StartApplication;
import org.feng.demofx.dao.impl.AnimalDao;
import org.feng.demofx.entity.Animal;
import org.feng.demofx.enums.AnimalTypeEnum;
import org.feng.demofx.sys.PageNodeKey;
import org.feng.demofx.sys.PageNodeRender;
import org.feng.demofx.util.ControlUtil;
import org.feng.demofx.util.StyleUtil;
import org.feng.demofx.util.TableColumnUtil;
import org.feng.demofx.vo.AnimalVo;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 动物管理界面
 *
 * @author feng
 */
@PageNodeKey(value = AnimalManagePage.PAGE_KEY, pageName = "动物管理")
public class AnimalManagePage implements PageNodeRender {
    public static final String PAGE_KEY = "animalManage";

    private static AnimalDao animalDao = new AnimalDao();

    @Override
    public Node render(Pane pane) {
        VBox vbox = new VBox();
        vbox.setAlignment(Pos.TOP_CENTER);
        // 页面标题
        Label title = new Label("动物管理页面");
        StyleUtil.setFont(title, Color.BLACK, 20);
        vbox.getChildren().add(title);

        // 操作按钮
        VBox oper = new VBox();
        oper.setAlignment(Pos.TOP_LEFT);
        oper.setMaxWidth(((StartApplication.SCREEN_WIDTH * 0.8) - StartApplication.LEFT_MENU_WIDTH) * 0.8);
        oper.setMaxHeight(200);
        HBox hBox = new HBox();
        oper.getChildren().add(hBox);
        vbox.getChildren().add(oper);
        hBox.setMaxWidth(170);
        Button addButton = ControlUtil.genAddButton();
        Button updateButton = ControlUtil.genUpdateButton();
        Button deleteButton = ControlUtil.genDeleteButton();
        hBox.getChildren().add(addButton);
        Node spacer1 = new Region();
        HBox.setHgrow(spacer1, Priority.ALWAYS);
        hBox.getChildren().add(spacer1);
        hBox.getChildren().add(updateButton);
        Node spacer2 = new Region();
        HBox.setHgrow(spacer2, Priority.ALWAYS);
        hBox.getChildren().add(spacer2);
        hBox.getChildren().add(deleteButton);

        // 设置外边距，上、右，下，左
        oper.setPadding(new Insets(10, 0, 12, 0));
        // 表格视图
        TableView<AnimalVo> animalTableView = new TableView<>();
        // 设置可编辑
        animalTableView.setEditable(true);
        // 表格宽度
        animalTableView.setMaxWidth(((StartApplication.SCREEN_WIDTH * 0.8) - StartApplication.LEFT_MENU_WIDTH) * 0.8);
        // 设置可选择多行数据
        animalTableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        // 解析表头和列信息
        TableColumnUtil.parseColumnsByClass(animalTableView.getColumns(), AnimalVo.class);
        // 添加表格数据
        ObservableList<AnimalVo> data = FXCollections.observableArrayList();
        data.addAll(list());
        animalTableView.setItems(data);
        vbox.getChildren().add(animalTableView);

        // 控制台输入操作记录
        LogTextAreaComponent logger = new LogTextAreaComponent(400, animalTableView.getMaxWidth());
        vbox.getChildren().add(logger.getLogBox());

        // 当选择发生变化时调用该函数-选择某一行时
        animalTableView.getSelectionModel().selectedItemProperty().addListener((obs, oldVal, newVal) -> {
            if (newVal != null && !animalTableView.getSelectionModel().isSelected(newVal.getId())) {
                logger.log("已选择 " + newVal.getName());
            }
        });

        // 注册删除
        deleteButton.setOnAction(ControlUtil.alertConfirm("确认删除吗？", "", buttonType -> {
            ButtonBar.ButtonData buttonData = buttonType.getButtonData();
            if (buttonData.isDefaultButton()) {
                // 确认删除
                ObservableList<AnimalVo> items = animalTableView.getSelectionModel().getSelectedItems();
                List<Long> ids = items.stream().mapToLong(vo -> Long.valueOf(vo.getId())).boxed().toList();
                logger.log("正在删除 " + items.stream().map(AnimalVo::getName).collect(Collectors.joining(",")));
                animalDao.delete(ids);

                // 刷新列表
                ObservableList<AnimalVo> newData = FXCollections.observableArrayList();
                newData.addAll(list());
                animalTableView.setItems(newData);
                logger.log("删除 " + items.stream().map(AnimalVo::getName).collect(Collectors.joining(",")) + "成功！");
            }
        }));

        // 注册新增
        addButton.setOnAction(event -> {
            // 定义网格面板
            GridPane gridPane = new GridPane();
            // 设置垂直间距，水平间距
            gridPane.setVgap(10);
            gridPane.setHgap(5);
            Label nameLabel = new Label("名字 ");
            TextField nameTextField = new TextField();
            Label ageLabel = new Label("年龄 ");
            TextField ageTextField = new TextField();
            Label typeLabel = new Label("类型 ");
            ComboBox<String> typeComboBox = new ComboBox<>();
            typeComboBox.getItems().addAll(Arrays.stream(AnimalTypeEnum.values()).map(AnimalTypeEnum::getDesc).toList());
            typeComboBox.setValue(AnimalTypeEnum.UN_KNOW.getDesc());

            gridPane.add(nameLabel, 0, 0);
            gridPane.add(nameTextField, 1, 0);
            gridPane.add(ageLabel, 0, 1);
            gridPane.add(ageTextField, 1, 1);
            gridPane.add(typeLabel, 0, 2);
            gridPane.add(typeComboBox, 1, 2);

            DialogPane dialogPane = new DialogPane();

            dialogPane.setPrefHeight(300);
            dialogPane.setPrefWidth(500);
            dialogPane.setMaxHeight(400);
            dialogPane.setMaxWidth(550);

            dialogPane.setContent(gridPane);
            dialogPane.getButtonTypes().addAll(ButtonType.CANCEL, ButtonType.OK);
            Dialog<ButtonType> dialog = new Dialog<>();
            dialog.setDialogPane(dialogPane);

            dialog.showAndWait().ifPresent(buttonType -> {
                if (buttonType.getButtonData().isDefaultButton()) {
                    logger.log("开始新增数据");
                    // 获取文本框中数据
                    Animal animal = new Animal();
                    animal.setAge(Integer.parseInt(ageTextField.getText()));
                    animal.setName(nameTextField.getText());
                    // 获取下拉框的数据
                    String type = typeComboBox.getValue();
                    animal.setAnimalType(AnimalTypeEnum.getByDesc(type));
                    logger.log("正在新增 " + animal.getName());
                    // 添加动物
                    animalDao.add(animal);
                    data.add(AnimalVo.newInstance(animal));
                    logger.log("新增 " + animal.getName() + "成功！");
                }
            });
            dialog.close();
        });

        // 注册更新
        updateButton.setOnAction(event -> {
            // 定义网格面板
            GridPane gridPane = new GridPane();
            // 设置垂直间距，水平间距
            gridPane.setVgap(10);
            gridPane.setHgap(5);
            Label nameLabel = new Label("名字 ");
            TextField nameTextField = new TextField();
            Label ageLabel = new Label("年龄 ");
            TextField ageTextField = new TextField();
            Label typeLabel = new Label("类型 ");
            // 下拉条，设置默认值
            ComboBox<String> typeComboBox = new ComboBox<>();
            typeComboBox.getItems().addAll(Arrays.stream(AnimalTypeEnum.values()).map(AnimalTypeEnum::getDesc).toList());
            ObservableList<AnimalVo> selectedItems = animalTableView.getSelectionModel().getSelectedItems();
            if (selectedItems == null || selectedItems.size() != 1) {
                logger.log("请选择一条数据进行修改");
                return;
            }
            // 设置原值
            AnimalVo selectedAnimal = selectedItems.get(0);
            String originalName = selectedAnimal.getName();
            Integer originalAge = selectedAnimal.getAge();
            String originalAnimalType = selectedAnimal.getAnimalType();
            nameTextField.setText(originalName);
            ageTextField.setText(String.valueOf(selectedAnimal.getAge()));
            typeComboBox.setValue(selectedAnimal.getAnimalType());

            gridPane.add(nameLabel, 0, 0);
            gridPane.add(nameTextField, 1, 0);
            gridPane.add(ageLabel, 0, 1);
            gridPane.add(ageTextField, 1, 1);
            gridPane.add(typeLabel, 0, 2);
            gridPane.add(typeComboBox, 1, 2);

            DialogPane dialogPane = new DialogPane();
            dialogPane.setPrefHeight(300);
            dialogPane.setPrefWidth(500);
            dialogPane.setMaxHeight(400);
            dialogPane.setMaxWidth(550);

            dialogPane.setContent(gridPane);
            dialogPane.getButtonTypes().addAll(ButtonType.CANCEL, ButtonType.OK);
            Dialog<ButtonType> dialog = new Dialog<>();
            dialog.setDialogPane(dialogPane);

            dialog.showAndWait().ifPresent(buttonType -> {
                if (buttonType.getButtonData().isDefaultButton()) {
                    logger.log("开始修改数据");
                    // 获取文本框中数据
                    Animal animal = new Animal();
                    animal.setId(selectedAnimal.getId().longValue());
                    animal.setAge(Integer.parseInt(ageTextField.getText()));
                    animal.setName(nameTextField.getText());
                    // 获取下拉框的数据
                    String type = typeComboBox.getValue();
                    animal.setAnimalType(AnimalTypeEnum.getByDesc(type));
                    logger.log(String.format("正在修改ID为【%s】,名字为【%s】 ", selectedAnimal.getId(), originalName));

                    // 更新动物
                    animalDao.update(animal);
                    // 更新视图
                    for (AnimalVo next : data) {
                        if (next.getId().equals(animal.getId().intValue())) {
                            next.setAnimalType(animal.getAnimalType().getDesc());
                            next.setName(animal.getName());
                            next.setAge(animal.getAge());
                            break;
                        }
                    }
                    logger.log(String.format("修改完成! ID为【%s】，修改名字【%s】为【%s】，动物类型【%s】为【%s】，年龄【%s】为【%s】", selectedAnimal.getId(), originalName, animal.getName(),
                            originalAnimalType, animal.getAnimalType().getDesc(), originalAge, animal.getAge()));
                }
            });
            dialog.close();
        });

        return vbox;
    }

    private List<AnimalVo> list() {
        return animalDao.listAll().stream().map(AnimalVo::newInstance).collect(Collectors.toList());
    }
}
